package org.dromara.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.domain.PageData;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.web.core.BaseService;
import org.dromara.system.domain.SysDictData;
import org.dromara.system.mapper.SysDictDataMapper;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 字典 业务层处理
 */
@RequiredArgsConstructor
@Service
public class SysDictDataServiceImpl extends BaseService {

  private final SysDictDataMapper baseMapper;

  public TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData, PageQuery pageQuery) {

    LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
    Page<SysDictData> page = pageQuery.build();
    Page<SysDictData> list = baseMapper.selectPage(page, lqw);


    return TableDataInfo.build(list);
  }

  /**
   * 根据条件分页查询字典数据
   *
   * @param dictData 字典数据信息
   * @return 字典数据集合信息
   */
  public List<SysDictData> selectDictDataList(SysDictData dictData) {
    LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
    return baseMapper.selectList(lqw);
//        LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
//        return baseMapper.selectVoList(lqw);
  }

  private LambdaQueryWrapper<SysDictData> buildQueryWrapper(SysDictData bo) {
    LambdaQueryWrapper<SysDictData> lqw = Wrappers.lambdaQuery();
    lqw.eq(bo.getSort() != null, SysDictData::getSort, bo.getSort());
    lqw.like(StringUtils.isNotBlank(bo.getName()), SysDictData::getName, bo.getName());
    lqw.eq(StringUtils.isNotBlank(bo.getType()), SysDictData::getType, bo.getType());
    lqw.orderByAsc(SysDictData::getSort);
    return lqw;
  }

  /**
   * 根据字典类型和字典键值查询字典数据信息
   *
   * @param dictType  字典类型
   * @param dictValue 字典键值
   * @return 字典标签
   */
  public SysDictData selectDictLabel(String dictType, String dictValue) {
    return baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
      .select(SysDictData::getName)
      .eq(SysDictData::getType, dictType)
      .eq(SysDictData::getValue, dictValue));
  }

  /**
   * 根据字典数据ID查询信息
   *
   * @param dictId 字典数据ID
   * @return 字典数据
   */
  public SysDictData selectDictDataById(Long dictId) {
    return baseMapper.selectById(dictId);
  }

  /**
   * 批量删除字典数据信息
   * @param dictCodes 需要删除的字典数据ID
   */
  public void deleteDictDataByIds(Long[] dictCodes) {
    for (Long dictCode : dictCodes) {
      SysDictData data = baseMapper.selectById(dictCode);
      baseMapper.deleteById(dictCode);
      CacheUtils.evict(CacheNames.SYS_DICT, data.getType());
    }
  }

  /**
   * 新增保存字典数据信息
   *
   * @param bo 字典数据信息
   * @return 结果
   */
  @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.type")
  public List<SysDictData> insertDictData(SysDictData bo) {
    PageData res = this.validEntityBeforeSave(bo);
    int row = 0;
    if (res.isSuccess()){
      row = baseMapper.insert(bo);
    }
    if (row > 0) {
      return baseMapper.selectList(new LambdaQueryWrapper<SysDictData>()
        .eq(SysDictData::getType, bo.getType())
        .orderByAsc(SysDictData::getSort));
    }
    throw new ServiceException("操作失败");
  }

  /**
   * 修改保存字典数据信息
   * @param bo 字典数据信息
   * @return 结果
   */
  @CachePut(cacheNames = CacheNames.SYS_DICT, key = "#bo.type")
  public List<SysDictData> updateDictData(SysDictData bo) {
    PageData res = this.validEntityBeforeSave(bo);
    int row = 0;
    if (res.isSuccess()){
      row = baseMapper.updateById(bo);
    }
    if (row > 0) {
      return baseMapper.selectList(new LambdaQueryWrapper<SysDictData>()
        .eq(SysDictData::getType, bo.getType())
        .orderByAsc(SysDictData::getSort));
    }
    throw new ServiceException("操作失败");
  }

  /**
   * 保存前的数据校验
   */
  private PageData validEntityBeforeSave(SysDictData bo) {
    //TODO 做一些数据校验,如唯一约束
    PageData res = new PageData();
    List<SysDictData> list = baseMapper.selectList(
      new LambdaQueryWrapper<SysDictData>()
        .eq(SysDictData::getType, bo.getType())
        .eq(SysDictData::getValue, bo.getValue()));
    if (list.size() > 0 && bo.getDataId() == null) {
//      同一个字典下，值不可重复
      return res.error("同一个字典下，值不可重复");
    }
    return res.success();
  }

}
